Go

Impressions

  • Default Access Control  controlled by the case  of the identifier:

    • Bro .

    • Starting with uppercase letter: Public  (exported outside the package).

    • Starting with lowercase letter: Private  (accessible only within the same package).

  • Does not have null safety.

  • Nothing stood out to me. Not impressive and has few use cases.

  • Meh.

About

About
Memory
  • Has a Garbage Collector.

  • Can store memory addresses, just like C, using & and *.

Safety
  • Default:  controlled by the case  of the identifier:

    • Starting with uppercase letter: Public  (exported outside the package).

    • Starting with lowercase letter: Private  (accessible only within the same package).

    • This is widely disliked. I don’t like it and Prime hates it.

package main

type MyStruct struct { // Exported (public)
    PublicField int
    privateField int // Private to the package
}
Syntax
  • Static typing.

  • Has 'var' in function definitions; or you can use ':=' to define the type via value inference.

  • Must pay more attention to declared types.

    • int8, int16, uint16, etc.

  • Some low-level caveats exist, despite the syntax being relatively simple.

  • Multiple variables can be defined on a single line, just like Python.

  • Functions can have multiple return values.

something := 2

import 'fmt'
fmt.println('hi')

Goroutines

  1. Concurrency vs Parallelism :

    • Goroutines provide concurrency (logical simultaneous execution)

    • Parallel execution requires multiple OS threads

  2. Default Behavior :

    • By default, Go uses GOMAXPROCS=1, meaning goroutines run on a single OS thread (not parallel)

    • They’re multiplexed onto this thread via cooperative scheduling

  3. Parallel Execution :

    • When GOMAXPROCS > 1 (set to number of CPU cores by default since Go 1.5)

    • The Go scheduler can distribute goroutines across multiple OS threads

    • These threads can then run in parallel on multiple CPU cores

  4. Important Notes :

    • Even with GOMAXPROCS>1, parallelism isn’t guaranteed - it depends on:

      • Available CPU cores

      • Workload characteristics

      • Scheduler decisions

    • Goroutines are much lighter than OS threads (can have millions)

  • To check/change GOMAXPROCS:

    fmt.Println(runtime.GOMAXPROCS(0)) // Get current value
    runtime.GOMAXPROCS(4)             // Set to 4 threads
    
How Goroutines Resemble a Job System (When GOMAXPROCS > 1 )
  • Similarities :

    • Worker Pool Analogy :

      • Each OS thread ( GOMAXPROCS ) acts like a worker in a thread pool

      • The Go scheduler assigns goroutines (jobs) to these workers

    • Work-Stealing Behavior :

      • If one OS thread (worker) runs out of goroutines, it can "steal" goroutines from another thread's queue

      • Similar to how modern job systems optimize load balancing

    • Task Granularity :

      • Goroutines are like small, independent units of work (tasks/jobs)

      • The scheduler manages their distribution across workers

  • Differences :

    • M:N Scheduling :

      • Go uses M goroutines mapped to N OS threads (where M ≫ N)

      • More efficient than 1:1 thread-per-task systems

    • Cooperative Scheduling :

      • Goroutines yield control at specific points (channel ops, syscalls, etc.)

      • Unlike preemptive OS thread scheduling

    • Automatic Management :

      • No manual "submit job" API needed - just go func()

      • Scheduler handles balancing automatically

  • What You Might Lose with Go :

    • Precise Control :

      • Can’t pin goroutines to specific cores

      • Limited influence over scheduler decisions

    • GC Pauses :

      • Though usually sub-millisecond, can affect some low-latency apps

  • Concurrency in Go .

    • Goroutines and Channels.

  • Goroutines crash course .

    • Goroutines are not parallel by default, they are concurrent.

package main

import (
    "fmt"
    "log"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    // Check HTTP method
    if r.Method != http.MethodGet {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }

    // Get a "name" parameter from URL (ex: /hello?name=John)
    name := r.URL.Query().Get("name")
    if name == "" {
        name = "world"
    }

    // Respond with a personalized message
    message := fmt.Sprintf("Hello, %s!", name)
    w.WriteHeader(http.StatusOK)
    w.Write([]byte(message))
}

func main() {
    // Set up the /hello route
    http.HandleFunc("/hello", helloHandler)

    // Start the server on port 8080
    fmt.Println("Server running at http://localhost:8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatalf("Error starting server: %v", err)
    }
}

Godot

Godot Go